<?php

declare(strict_types=1);

namespace Gwl\Framework\Foundation;

use DI\Container;
use Gwl\Framework\Event\EventServiceProvider;
use Gwl\Framework\Foundation\Http\Kernel;
use Gwl\Framework\Log\LogServiceProvider;
use Gwl\Framework\Routing\RoutingServiceProvider;
use Gwl\Framework\Support\ServiceProvider;
use Symfony\Component\HttpFoundation\Request;

class Application implements \ArrayAccess
{
    /**
     * @var Container
     */
    protected $container;

    protected $serviceProviders = [];

    protected $bootstrapped = false;

    public static $instance = false;

    use ContainerTrait;

    public function __construct(Container $container)
    {
        $this->container = $container;
        $this->registerBaseServiceProviders();
        self::$instance = $this;
    }

    //注册基础服务
    protected function registerBaseServiceProviders()
    {
        $this->register(new EventServiceProvider($this));
        $this->register(new RoutingServiceProvider($this));
    }

    //配置文件地址
    public function configPath()
    {
        return BASE_PATH."/config";
    }

    //服务注册
    protected function register($provider)
    {
        $providerName = is_string($provider) ? $provider : get_class($provider);
        if ($registed = $this->getProvider($providerName)){
            return $registed;
        }
        if (is_string($provider)){
            $provider = $this->container->get($provider);
        }
        $provider->register();
        return $this->serviceProviders[$providerName] = $provider;
    }

    //服务加载
    protected function bootProvider(ServiceProvider $provider)
    {
        if (method_exists($provider, 'boot')) {
            $provider->boot();
        }
    }

    //加载所有服务
    public function boot()
    {
        array_walk($this->serviceProviders, function ($provider) {
            $this->bootProvider($provider);
        });
    }


    protected function getProvider($name)
    {
        return $this->serviceProviders[$name] ?? null;
    }

    public function registerConfiguredProviders()
    {
          foreach ($this->get('config')->get('app.providers') as $item){
              $this->register($item);
          }
    }

    //启动加载器
    public function withBootstrap($bootstrap)
    {
        if ($this->bootstrapped){
            return;
        }
        foreach ($bootstrap as $item){
           $this->make($item)->bootstrap($this);
        }
    }

    //运行应用程序
    public function run()
    {
        $request  = Request::createFromGlobals();
        $response = $this->container->get(Kernel::class)->handle($request);
        $response->send();
    }
}